/******************************************************************************
// * 文件名：AiP33626.c
// *   作者：
// *   版本：
// *   介绍：AiP33626 通用基础函数、初始化函数
******************************************************************************/

/* 头文件 -------------------------------------------------------------------*/
#include"AIP33626.H"

/* 宏定义 -------------------------------------------------------------------*/

/* 变量 ---------------------------------------------------------------------*/
uint8_t  Aip33626_Run = 0;
uint8_t  Aip33626_Rundata[Address_seg_num*Address_com_num] = {0};
uint8_t  Aip33626_Pwmdata[Address_seg_num*Address_com_num] = {0};
/* AiP33626寄存器说明 -------------------------------------------------------*/

/**
 * @brief Reg1 defination
 * Reset : 0x00
 * ------------
 * Bit7 : 0
 * Bit6 : 0
 * Bit5 : I5
 * Bit4 : I4
 * Bit3 : I3
 * Bit2 : I2
 * Bit1 : I1
 * Bit0 : I0
 * ------------
 * Inter Ris Seg current = 0.375mA * (17 + I[5:0])
 */



/**
 * @brief Reg2 defination
 * Reset : 0x40
 * ------------
 * Bit7 : 0
 * Bit6 : 1
 * Bit5 : 0
 * Bit4 : 0
 * Bit3 : G_N3
 * Bit2 : G_N2
 * Bit1 : G_N1
 * Bit0 : G_N0
 * ------------
 * G_N[3:0] 
 * 0 : Grid1
 * 1 : Grid1~2
 * ...
 * 7 : Grid1~8    有效
 * 8~15 : 禁用
 */



/**
 * @brief Reg4 defination
 * Reset : 0x50
 * ------------
 * Bit7 : 0
 * Bit6 : 1
 * Bit5 : 0
 * Bit4 : 1
 * Bit3 : DT1
 * Bit2 : DT0
 * Bit1 : TP2
 * Bit0 : TP1
 * ------------
 * DT[1:0]=00,dead zone time= 4*closck
 * DT[1:0]=01,dead zone time= 8*closck
 * DT[1:0]=10,dead zone time= 16*closck
 * DT[1:0]=11,dead zone time= 24*closck
 * ------------
 * TP2=1,过温保护2关闭
 * TP2=0,过温保护2开启（150°C左右关闭SEG输出）
 * ------------
 * TP1=1,过温保护1关闭
 * TP1=0,过温保护2开启（125°C左右SEG输出电流降低设置的1/3）
 */



/**
 * @brief Reg5 defination
 * Reset : 0x60
 * ------------
 * Bit7 : 0
 * Bit6 : 1
 * Bit5 : 1
 * Bit4 : 0
 * Bit3 : SVGD(0:if Iseg<10mA configure )(1:if Iseg≥10mA configure)
 * Bit2 : ADS(0:RAM adress start from 0x00)(1:RAM adress start from AD[7:0])
 * Bit1 : 0
 * Bit0 : SLEEP (0:disable sleep command)(1:enable sleep command)
 * ------------
 */


/**
 * @brief Reg6 defination
 * Reset : 0x80
 * ------------
 * Bit7 : 1
 * Bit6 : 0
 * Bit5 : 0
 * Bit4 : 0
 * Bit3 : FR1
 * Bit2 : FR0
 * Bit1 : DON(0:display OFF)(1:display ON)
 * Bit0 : GS (0:shadow cancel OFF)(1:shadow cancel ON)
 * ------------
 * FR[1:0]=00,400Hz
 * FR[1:0]=01,800Hz
 * FR[1:0]=10,1600Hz
 * FR[1:0]=11,3200Hz
 * ------------
 */



/**
 * @brief Reg8 defination
 * Reset : 0x90
 * ------------
 * Bit7 : 1
 * Bit6 : 0
 * Bit5 : 0
 * Bit4 : 1
 * Bit3 : 0
 * Bit2 : 0
 * Bit1 : GRE (0:soft reset off)(1:soft reset on)
 * Bit0 : LVRE(0:LVR_2V off)(1:0:LVR_2V on)
 * ------------

 */


/**
 * @brief Reg10 defination
 * Reset : 0xC0
 * ------------
 * Bit7 : 1
 * Bit6 : 1
 * Bit5 : 0
 * Bit4 : 0
 * Bit3 : AD7
 * Bit2 : AD6
 * Bit1 : AD5
 * Bit0 : AD4
 * ------------
 * AD[7:4] 地址高位设定值，即GRID列选择；仅在ADS=1有效
 */


/**
 * @brief Reg11 defination
 * Reset : 0xE0
 * ------------
 * Bit7 : 1
 * Bit6 : 1
 * Bit5 : 1
 * Bit4 : 0
 * Bit3 : AD3
 * Bit2 : AD2
 * Bit1 : AD1
 * Bit0 : AD0
 * ------------
 * AD[3:0] 地址低位设定值，即GRID列选择；仅在ADS=1有效
   AD[7:0] 中设定值只在ADS=1时改变写入RAM的首地址，如果ADS=0,该寄存器写值不影响RAM首地址。
 */
/**
 * @funtion    Delay_us
 * @brief      US延时
 * @param[in]  无     
 * @param[out] 无
 * @return     无
 */
void Sys_Delay_us(unsigned int us)
{
    unsigned int x;
    x = us;
    while(x--)
    {
        _nop_();
        _nop_(); 
        _nop_();
        clrwdt();
    }
}


/**********************************************************
//	*	函数名称：总线空闲保持
//	*	功		能：
//	*	参		数：无
//	*	返 回 值：无
***********************************************************/
void IIC_HOLD(void)
{
    AiP33626_SCL_OUT();
    AiP33626_SDA_OUT();
    Sys_Delay_us(1);
    AiP33626_SDA=1;
    Sys_Delay_us(1);
    AiP33626_SCL=1;
    Sys_Delay_us(10);   
}
/**********************************************************
//	*	函数名称：IIC开始函数
//	*	功		能：IIC——START
//	*	参		数：无
//	*	返 回 值：无
***********************************************************/
void AiP33626_start(void)			//开始信号,SCL为高时，SDA下降沿
{													
	AiP33626_SDA = 1;
	Sys_Delay_us(1);
	AiP33626_SCL = 1;
	Sys_Delay_us(1);
	AiP33626_SDA = 0;
	Sys_Delay_us(1);
	AiP33626_SCL = 0;
	Sys_Delay_us(1);
}

/**********************************************************
//	*	函数名称：IIC停止函数
//	*	功		能：IIC-STOP
//	*	参		数：无
//	*	返 回 值：无
***********************************************************/
void AiP33626_stop(void)			//停止信号,SCL为高时，SDA上升沿
{													
	AiP33626_SCL = 0;
	Sys_Delay_us(1);
	AiP33626_SDA = 0;
	Sys_Delay_us(1);
	AiP33626_SCL = 1;
	Sys_Delay_us(1);
	AiP33626_SDA = 1;
	Sys_Delay_us(1);
}
/**********************************************************
//	*	函数名称：IIC_ACK函数
//	*	功		能：从机发出应答主机（单片机）接收
//	*	参		数：无
//	*	返 回 值：无
***********************************************************/
void AiP33626_ACK(void)  //此处不判定ACK是否一定为低，保持第九个时钟有
{
    AiP33626_SCL=0;
    Sys_Delay_us(1);
    AiP33626_SDA_IN();              //SDA设置为输入态
    AiP33626_SCL=1;
    Sys_Delay_us(1);      //区分ACK脉宽
    Sys_Delay_us(1);
    Sys_Delay_us(1);
    AiP33626_SCL=0;
    AiP33626_SDA_OUT();;              //SDA设置为输出态
    Sys_Delay_us(1);
}

/**********************************************************
//	*	函数名称：数据传输
//	*	功		能：写8bit数据
//	*	参		数：dat（发送到数据）
//	*	返 回 值：无
***********************************************************/
void AiP33626_write(unsigned char dat)	//写8bit数据
{
	unsigned char i;
	for(i = 0; i < 8; i++)
	{		
		AiP33626_SCL = 0;
		Sys_Delay_us(1);
		AiP33626_SDA = dat & 0x80;
		Sys_Delay_us(1);
		AiP33626_SCL = 1;
		dat <<= 1;
		Sys_Delay_us(1);	 
	} 
}
/**********************************************************
//	*	函数名称：命令数据传输
//	*	功		能：发送8bit命令
//	*	参		数：cmd（发送到命令）
//	*	返 回 值：无
***********************************************************/
void AiP33626_Write_CMD(unsigned char cmd)				//写8位指令
{
	AiP33626_start();					            //开始
	AiP33626_write(Address_Write_00);
	AiP33626_ACK();
	AiP33626_write(cmd);				            //写入命令
	AiP33626_ACK();
	AiP33626_stop();					              //结束
}
/**********************************************************
//	*	函数名称：连续地址写控制数据
//	*	功		能：连续地址写
//	*	参		数：
//	*	返 回 值：无
***********************************************************/
void AiP33626_I2C_Write_128(unsigned char dat)
{
	unsigned char i;
	AiP33626_start();					   //开始
	AiP33626_write(Address_Write_00);
	AiP33626_ACK();	
	AiP33626_write(0x6C);				//写入地址
	AiP33626_ACK();
    for(i = 0;i < Address_seg_num*Address_com_num;i++)
    {
        if(Aip33626_Rundata[i])
        {
            if(Aip33626_Pwmdata[i])
            {
                AiP33626_write(dat);			  //亮度
                AiP33626_ACK();	
            }
            else
            {
                AiP33626_write(0x10);			  //亮度
                AiP33626_ACK();	
            }
        }
        else
        {
            AiP33626_write(0);			  //亮度
            AiP33626_ACK();	
        }
    }
    AiP33626_stop();					    //结束
}
/**********************************************************
//	*	函数名称：固定地址写数据
//	*	功		能：固定地址写
//	*	参		数：
//	*	返 回 值：无
***********************************************************/
void AiP33626_I2C_Write_Single(unsigned char GRIDn,unsigned char SEGn,unsigned char PWMn,unsigned char Lengethn)
{
	unsigned char i;
	AiP33626_Write_CMD(0xC0+GRIDn);
	AiP33626_Write_CMD(0xE0+SEGn);

	AiP33626_start();					   //开始
	AiP33626_write(Address_Write_00);
	AiP33626_ACK();	
	AiP33626_write(0x6C);				//写入地址
	AiP33626_ACK();	
	for(i=0;i<Lengethn;i++)
	{
		AiP33626_write(PWMn);			 //初始化数据
		AiP33626_ACK();	
	}
	AiP33626_stop();					 //结束
}
/**********************************************************
//	*	函数名称：芯片初始化
//	*	功		能：初始化内部寄存器及显示数据
//	*	参		数：
//	*	返 回 值：
***********************************************************/
void AiP33626_init(void)
{
	AiP33626_Write_CMD(0x3f);//最大电流
	AiP33626_Write_CMD(0x47);//GRID1~GRID8均有效
	AiP33626_Write_CMD(0x53);//死区时间为四个时钟周期/无过温保护
	AiP33626_Write_CMD(0x6C);//使用大于10mA电流配置/RAM从0x00开始/使用内部电阻/不睡眠
	AiP33626_Write_CMD(0x87);//使用800HZ扫描/开显示/开消影
	AiP33626_Write_CMD(0x91);//不使用全局复位/使能LVR功能	
	AiP33626_Write_CMD(0xC0);//RAM地址高位（GRID列）
    AiP33626_Write_CMD(0xE0);//RAM地址低位（SEG行）
}
/**********************************************************
//	*	函数名称：驱动
//	*	功		能：初始化内部寄存器及显示数据
//	*	参		数：
//	*	返 回 值：
***********************************************************/
void AiP33626_driver(void)
{
    if(Aip33626_Run == 0)
    {
        //总线置空闲
        IIC_HOLD();        
        //AiP33626初始化   
        AiP33626_init();
        AiP33626_I2C_Write_128(0x00);//写入LED灯全灭
        Aip33626_Run = 1;
    }
    else
    { 
        AiP33626_I2C_Write_128(0xff);
    }
}
